blah blah blah blah blah blah. Back to the rambling and ranting.
May 27, 2018
RecyclerViews have lot of parts--a LOT of parts! And they work together in sometimes obvious ways, but all too often in very counter-intuitive ways. I've done several by now, but I always have to look things up. I never remember all the details, and some aspects I just gloss over to get it done and working (especially when I'm nearing the end!). So this is an attempt at formalizing my knowledge of this oh-so-necessary UI element. And if it helps anyone, that's icing on the cake.
Here's a non-definitive list of the parts of a working RecyclerView. The basic/required components are in bold.
I recently found a relatively decent (but very basic) explanation of the relationships between these components here. This diagram comes from margaretsitati1's web site, so give her a high-five for me!
And then there's the ViewHolder! While conceptually simple, somehow the autistic people at Google have turned the Viewholder concept into something oddly complicated and inexplicable. Here are some diagrams to spin your head from a couple of Google Developers (Adam Powell and Yigit Boyar obfuscating their work in 2016). If you want to get even more confused, feel free to watch their presentation on youtube.
In many companies, the more complex something sounds, the more likely managers will approve it and just let the engineers go about their business. They don't want to look like idiots by asking questions. And we all know how vain management can be. Clearly these guys were given free rein without any thought to conceptual clarity. Thanks, Google!
The key for me is the data--it's what you want to display, right? My question has always been, where do you hold it? Do you keep it in the Activity/Fragment that displays the RecyclerView, or should it be kept in the Adapter, or perhaps somewhere else? (The somewhere else might make a lot of sense if it needs to live in a seperate thread or a Service--just thought you might ask.)
Up to now, I've always assembled the data in the encapsulating Activity or Fragment. That makes things easy because here we have a Context and easy access to ASyncTasks, both very important for accessing all aspects of Android systems and to keep potentially long processes out of the main thread.
But I usually pass this data to the Adapter, which is where the manipulations by the user are best handled. I also pass a Context to the Adapter, so allow the Adapter access to all those goovy Android systems. Once the Adapter has been created, the Activity/Fragment can forget about the data and go about working on the higher level stuff. This leaves the Adapter to update and save all changes.
Of course all this is made ever more complicated due to the Activity/Fragment lifecycle--the bane of Android programming (and probably the source of half of all the hard bugs!). But I digress.
But Adapters don't have good access to AsyncTasks. Rajesh on Stackoverflow even suggests that you should nest both your Adapter AND your ASyncTask within an Activity so they can all access each other. Well, I don't like this at all: it violates all sorts of OOP ideas like encapsulation, it bloats your Activity/Fragment files, and creates a maze of inter-dependent inner classes that's a big mess to debug.
At the moment, I haven't had data large enough to slow things down, nor have I had to deal with especially slow data retrievals (like internet access). So I have simply avoided the problem. But that's no answer--in fact it's a big cop-out, which I readily acknowledge.
Up to now all my data have simply been ArrayLists, and short ones at that. And you know what? RecyclerViews are great at that! Perhaps that's all the people at Google thought would be done. Their UI team has never been accused of long-term practicality (most of them usually just focus on their own pet-projects and let the rest of the world go to Hell--but we all know that).
I'm not going into how Android makes MVP impossible; I'll save that for another day. I'm just talking about where to store the data. And to be honest, I feel very uncomfortable keeping it in the Adapter. But until I figure out or stumble upon a better way, that's where I'm doing it.
Please feel free to express your opinions. I'd really like to hear what you think.
Next up, coupling RecyclerView with Cursors (so you can display what's in a database!).
"Android Evolution" created by Manu Cornet, http://www.bonkersworld.net. All else is copyright 2018 by Scott M. Biggs and Sleep Furiously Productions. Not that that means much these days.